import * as _ from 'lodash';
import { pipe } from 'fp-ts/function';
import {
  IPublicTypeNodeSchema,
  isNodeSchema,
  IPublicTypeNodeDataType,
  IPublicTypeCompositeValue,
} from '@alilc/lowcode-types';

import {
  IScope,
  CodeGeneratorError,
  PIECE_TYPE,
  CodePiece,
  NodeGenerator,
  NodeGeneratorConfig,
  NodePlugin,
  AttrData,
  AttrPlugin,
} from '../types';

import { generateCompositeType } from './compositeType';
import { getStaticExprValue } from './common';
import { executeFunctionStack } from './aopHelper';
import { encodeJsxStringNode } from './encodeJsxAttrString';
import { unwrapJsExprQuoteInJsx } from './jsxHelpers';
import { isValidIdentifier } from './validate';
import { EnhancedStyleTransformer } from '../utils/tailwind/enhancedTailwindTransformer';
import { isJSExpression, isJSFunction } from '@alilc/lowcode-utils';

const unExportPropNames = ['__events'];

const __log: any = () => {};

function mergeNodeGeneratorConfig(
  cfg1: NodeGeneratorConfig,
  cfg2: NodeGeneratorConfig = {},
): NodeGeneratorConfig {
  const resCfg: NodeGeneratorConfig = {};
  if (cfg1.handlers || cfg2.handlers) {
    resCfg.handlers = {
      ...(cfg1.handlers || {}),
      ...(cfg2.handlers || {}),
    };
  }

  if (cfg1.tagMapping || cfg2.tagMapping) {
    resCfg.tagMapping = cfg2.tagMapping || cfg1.tagMapping;
  }

  if (cfg1.attrPlugins || cfg2.attrPlugins) {
    resCfg.attrPlugins = [];
    resCfg.attrPlugins.push(...(cfg2.attrPlugins || []));
    resCfg.attrPlugins.push(...(cfg1.attrPlugins || []));
  }

  if (cfg1.nodePlugins || cfg2.nodePlugins) {
    resCfg.nodePlugins = [];
    resCfg.nodePlugins.push(...(cfg2.nodePlugins || []));
    resCfg.nodePlugins.push(...(cfg1.nodePlugins || []));
  }

  return resCfg;
}

export function isPureString(v: string) {
  // FIXME: 目前的方式不够严谨
  return (v[0] === "'" && v[v.length - 1] === "'") || (v[0] === '"' && v[v.length - 1] === '"');
}

function generateAttrValue(
  attrData: { attrName: string; attrValue: IPublicTypeCompositeValue },
  scope: IScope,
  config?: NodeGeneratorConfig,
): CodePiece[] {
  __log(
    '【generateAttrValue】处理属性:',
    attrData.attrName,
    '值类型:',
    attrData.attrValue && typeof attrData.attrValue === 'object' && 'type' in attrData.attrValue
      ? attrData.attrValue.type
      : typeof attrData.attrValue,
  );

  // 获取当前作用域中的所有绑定变量（可能是循环变量）
  const bindings = scope.bindings?.getAllBindings() || [];
  __log('【generateAttrValue】当前作用域中的绑定变量:', bindings);

  // 检查是否是事件处理函数（以on开头的属性）
  const isEventHandler = attrData.attrName.startsWith('on');
  __log('【generateAttrValue】是否是事件处理函数:', isEventHandler);

  // 检查属性值是否是JSFunction类型
  if (
    attrData.attrValue &&
    typeof attrData.attrValue === 'object' &&
    'type' in attrData.attrValue &&
    attrData.attrValue.type === 'JSFunction'
  ) {
    __log('【generateAttrValue】处理JSFunction类型属性');

    // 检查函数中是否包含循环变量引用
    const functionValue = (attrData.attrValue as any).value || '';
    __log('【generateAttrValue】函数值:', functionValue);

    const loopVars = bindings.filter((binding) => {
      const pattern = new RegExp(`\\bthis\\.${binding}\\b`, 'g');
      return pattern.test(functionValue);
    });
    __log('【generateAttrValue】检测到的循环变量:', loopVars);

    // 传递循环变量名称和属性名称给generateCompositeType
    const valueStr = generateCompositeType(attrData.attrValue, scope, {
      handlers: config?.handlers,
      nodeGenerator: config?.self,
      isAttrValue: true,
      attrName: attrData.attrName, // 传递属性名称
      loopItemName: loopVars.length > 0 ? loopVars[0] : undefined, // 第一个循环变量作为loopItemName
      loopIndexName: loopVars.length > 1 ? loopVars[1] : undefined, // 第二个循环变量作为loopIndexName
    });

    __log('【generateAttrValue】生成的函数值:', valueStr);

    return [
      {
        type: PIECE_TYPE.ATTR,
        name: attrData.attrName,
        value: valueStr,
      },
    ];
  }

  // 特殊处理children属性
  if (attrData.attrName === 'children' && attrData.attrValue) {
    // 当children是JSExpression类型时
    if (
      typeof attrData.attrValue === 'object' &&
      'type' in attrData.attrValue &&
      attrData.attrValue.type === 'JSExpression'
    ) {
      __log('【generateAttrValue】特殊处理JSExpression类型children属性');

      // 直接使用表达式值，不进行HTML实体编码
      const valueStr = generateCompositeType(attrData.attrValue, scope, {
        handlers: config?.handlers,
        nodeGenerator: config?.self,
        isAttrValue: true,
      });

      __log('【generateAttrValue】生成的JSExpression属性值:', valueStr);

      return [
        {
          type: PIECE_TYPE.ATTR,
          name: attrData.attrName,
          // 标记为JSExpression，后续处理时不会进行HTML实体编码
          value: valueStr,
          isJSExpression: true,
        },
      ];
    }
  }

  // 对于其他类型的属性，正常处理
  __log('【generateAttrValue】处理非JSFunction类型属性');
  const valueStr = generateCompositeType(attrData.attrValue, scope, {
    handlers: config?.handlers,
    nodeGenerator: config?.self,
    isAttrValue: true,
  });

  __log('【generateAttrValue】生成的属性值:', valueStr);

  return [
    {
      type: PIECE_TYPE.ATTR,
      name: attrData.attrName,
      value: valueStr,
    },
  ];
}

function generateAttr(
  attrName: string,
  attrValue: IPublicTypeCompositeValue,
  scope: IScope,
  config?: NodeGeneratorConfig,
): CodePiece[] {
  let pieces: CodePiece[];
  if (config?.attrPlugins) {
    pieces = executeFunctionStack<AttrData, CodePiece[], NodeGeneratorConfig>(
      { attrName, attrValue },
      scope,
      config.attrPlugins,
      generateAttrValue,
      config,
    );
  } else {
    pieces = generateAttrValue({ attrName, attrValue }, scope, config);
  }

  pieces = pieces.map((p) => {
    // FIXME: 在经过 generateCompositeType 处理过之后，其实已经无法通过传入值的类型判断传出值是否为纯字面值字符串了（可能包裹了加工函数之类的）
    //        因此这个处理最好的方式是对传出值做语法分析，判断以哪种模版产出 Attr 值
    let newValue: string;

    // 如果是JSExpression类型，直接使用大括号包裹，不进行HTML实体编码
    if (p.isJSExpression) {
      newValue = `{${p.value}}`;
    } else if (p.value && isPureString(p.value)) {
      // 似乎多次一举，目前的诉求是处理多种引号类型字符串的 case，正确处理转义
      const content = getStaticExprValue<string>(p.value);
      // console.log(
      //   'content: ',
      //   p.value.startsWith('"'),
      //   p.value,
      //   content,
      //   JSON.stringify(encodeJsxStringNode(content)),
      // );
      newValue = JSON.stringify(encodeJsxStringNode(content));
    } else {
      newValue = `{${p.value}}`;
    }
    // 处理 className 的特殊情况
    if (newValue.startsWith('"&#34;') && newValue.endsWith('&#34;"') && !newValue.includes('<')) {
      newValue = newValue.replaceAll('"&#34;', '"').replaceAll('&#34;"', '"');
    }
    const value = `${p.name}=${newValue}`;
    return {
      value,
      type: PIECE_TYPE.ATTR,
    };
  });

  return pieces;
}

function styleToClassName(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
) {
  if (!nodeItem) return;
  const { props } = nodeItem;
  if (Array.isArray(props)) {
  } else {
    const propNames = Object.keys(props || {});
    for (const propName of propNames) {
      const propValue = props[propName];
      if (propName === 'style') {
        const styleValue = generateCompositeType(propValue as IPublicTypeCompositeValue, scope, {
          handlers: config?.handlers,
          nodeGenerator: config?.self,
        });

        try {
          // 检查是否包含动态表达式（this.xxx 或其他变量引用）
          const hasDynamicExpression = /\bthis\.|[a-zA-Z_$][a-zA-Z0-9_$]*\s*\.\s*[a-zA-Z_$]/.test(
            styleValue,
          );

          if (hasDynamicExpression) {
            console.log('样式包含动态表达式，跳过转换:', styleValue);
            return; // 跳过转换，保持原始的 style 属性
          }

          // 尝试解析样式对象
          const styleObj = eval(`(${styleValue})`);
          // 使用 EnhancedStyleTransformer 的 mergeClassesToStyle 能力
          const classes = EnhancedStyleTransformer.mergeClassesToStyle([JSON.stringify(styleObj)]);
          if (!props.className) {
            props.className = classes;
            delete props.style;
          } else if (typeof props.className === 'string' && props.className) {
            props.className = `${props.className} ${classes}`;
            delete props.style;
          } else if (isJSExpression(props.className)) {
            // debugger;
            console.error('isJSExpression(props.className');
          }
        } catch (e) {
          console.warn('Style 转换失败:', styleValue, e);
        }
      }
    }
  }
}

function generateAttrs(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
): CodePiece[] {
  const { props } = nodeItem;

  // 处理css
  styleToClassName(nodeItem, scope, config);

  let pieces: CodePiece[] = [];

  if (props) {
    if (!Array.isArray(props)) {
      Object.keys(props)
        .filter((propName) => {
          if (propName === 'ref') {
            const allowRef = scope.refNames?.includes(props[propName] as string);
            return allowRef;
          }
          // 排除 children 属性，如果它应该作为子节点处理
          if (propName === 'children') {
            const childrenValue = props[propName];
            // 如果是组件对象，排除它
            if (
              typeof childrenValue === 'object' &&
              childrenValue !== null &&
              'componentName' in childrenValue
            ) {
              __log('【generateAttrs】排除children属性，因为它是组件对象');
              return false; // 排除这个属性，让它在generateSimpleNode中作为子节点处理
            }
            // 如果是字符串或JSExpression，也应该排除，作为子节点处理
            if (
              typeof childrenValue === 'string' ||
              (typeof childrenValue === 'object' &&
                childrenValue !== null &&
                'type' in childrenValue &&
                childrenValue.type === 'JSExpression')
            ) {
              __log(
                '【generateAttrs】排除children属性，因为它是字符串或JSExpression，应作为子节点处理',
              );
              return false; // 排除这个属性，让它在generateSimpleNode中作为子节点处理
            }
          }
          return !unExportPropNames.includes(propName);
        })
        .forEach((propName: string) => {
          const propValue = props[propName];
          if (isValidIdentifier(propName)) {
            pieces = pieces.concat(
              generateAttr(propName, props[propName] as IPublicTypeCompositeValue, scope, config),
            );
          }
        });
    } else {
      props.forEach((prop) => {
        if (prop.name && isValidIdentifier(prop.name) && !prop.spread) {
          pieces = pieces.concat(generateAttr(prop.name, prop.value, scope, config));
        }

        // TODO: 处理 spread 场景（<Xxx {...(something)}/>)
        // 这种在 schema 里面怎么描述
      });
    }
  }

  return pieces;
}

function generateBasicNode(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
): CodePiece[] {
  const pieces: CodePiece[] = [];
  const tagName = (config?.tagMapping || _.identity)(nodeItem.componentName);

  pieces.push({
    value: tagName || '', // FIXME: type detection error
    type: PIECE_TYPE.TAG,
  });

  return pieces;
}

function generateSimpleNode(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
): CodePiece[] {
  const basicParts = generateBasicNode(nodeItem, scope, config) || [];
  const attrParts = generateAttrs(nodeItem, scope, config) || [];
  const childrenParts: CodePiece[] = [];

  // 处理子节点
  let childrenToRender = nodeItem.children;

  // 检查 props.children 是否应该作为子节点处理
  if (nodeItem.props && !Array.isArray(nodeItem.props) && nodeItem.props.children) {
    const childrenValue = nodeItem.props.children;

    // 如果是组件对象，将其作为子节点处理
    if (
      typeof childrenValue === 'object' &&
      childrenValue !== null &&
      'componentName' in childrenValue
    ) {
      __log('【generateSimpleNode】检测到props.children是组件对象，将其作为子节点处理');
      childrenToRender = childrenValue as IPublicTypeNodeDataType;
    }
    // 如果是字符串，将其作为子节点处理
    else if (typeof childrenValue === 'string') {
      __log('【generateSimpleNode】检测到props.children是字符串，将其作为子节点处理');
      childrenToRender = childrenValue;
    }
    // 如果是JSExpression，将其作为子节点处理
    else if (
      typeof childrenValue === 'object' &&
      childrenValue !== null &&
      'type' in childrenValue &&
      childrenValue.type === 'JSExpression'
    ) {
      __log('【generateSimpleNode】检测到props.children是JSExpression，将其作为子节点处理');
      childrenToRender = childrenValue as IPublicTypeNodeDataType;
    }
  }

  if (childrenToRender && config?.self) {
    const childrenStr = config.self(childrenToRender, scope);

    childrenParts.push({
      type: PIECE_TYPE.CHILDREN,
      value: childrenStr,
    });
  }

  return [...basicParts, ...attrParts, ...childrenParts];
}

function linkPieces(pieces: CodePiece[]): string {
  const tagsPieces = pieces.filter((p) => p.type === PIECE_TYPE.TAG);
  if (tagsPieces.length !== 1) {
    throw new CodeGeneratorError('Only one tag definition required', tagsPieces);
  }
  const tagName = tagsPieces[0].value;

  const beforeParts = pieces
    .filter((p) => p.type === PIECE_TYPE.BEFORE)
    .map((p) => p.value)
    .join('');

  const afterParts = pieces
    .filter((p) => p.type === PIECE_TYPE.AFTER)
    .map((p) => p.value)
    .join('');

  const childrenParts = pieces
    .filter((p) => p.type === PIECE_TYPE.CHILDREN)
    .map((p) => p.value)
    .join('');

  let attrsParts = pieces
    .filter((p) => p.type === PIECE_TYPE.ATTR)
    .map((p) => p.value)
    .join(' ');

  attrsParts = attrsParts ? ` ${attrsParts}` : '';

  if (childrenParts) {
    return `${beforeParts}<${tagName}${attrsParts}>${childrenParts}</${tagName}>${afterParts}`;
  }

  return `${beforeParts}<${tagName}${attrsParts} />${afterParts}`;
}

function generateNodeSchema(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
): string {
  const pieces: CodePiece[] = [];
  if (config?.nodePlugins) {
    const res = executeFunctionStack<IPublicTypeNodeSchema, CodePiece[], NodeGeneratorConfig>(
      nodeItem,
      scope,
      config.nodePlugins,
      generateSimpleNode,
      config,
    );
    pieces.push(...res);
  } else {
    pieces.push(...generateSimpleNode(nodeItem, scope, config));
  }

  return linkPieces(pieces);
}

// TODO: 生成文档
// 为包裹的代码片段生成子上下文，集成父级上下文，并传入子级上下文新增内容。（如果存在多级上下文怎么处理？）
// 创建新的上下文，并从作用域中取对应同名变量塞到作用域里面？
// export function createSubContext() {}

/**
 * 递归处理节点中的循环变量引用
 * 将 this.loopItemName 替换为 loopItemName
 */
function processLoopVariables(
  node: IPublicTypeNodeSchema | any,
  loopItemName: string,
  loopIndexName: string,
  parentLoopVars: string[] = [],
): void {
  if (!node) return;

  // 处理数组类型的节点
  if (Array.isArray(node)) {
    node.forEach((item) => processLoopVariables(item, loopItemName, loopIndexName, parentLoopVars));
    return;
  }

  // 处理loop属性
  if (node.loop) {
    processPropertyValue(
      node.loop,
      loopItemName,
      loopIndexName,
      (newValue) => {
        node.loop = newValue;
      },
      parentLoopVars,
    );
  }

  // 处理condition属性
  if (node.condition) {
    processPropertyValue(
      node.condition,
      loopItemName,
      loopIndexName,
      (newValue) => {
        node.condition = newValue;
      },
      parentLoopVars,
    );
  }

  // 处理props
  if (node?.props) {
    Object.keys(node.props).forEach((propKey) => {
      const propValue = node.props[propKey];
      processPropertyValue(
        propValue,
        loopItemName,
        loopIndexName,
        (newValue) => {
          node.props[propKey] = newValue;
        },
        parentLoopVars,
      );
    });
  }

  // 处理子节点
  if (node.children) {
    if (Array.isArray(node.children)) {
      node.children.forEach((child) =>
        processLoopVariables(child, loopItemName, loopIndexName, parentLoopVars),
      );
    } else {
      processLoopVariables(node.children, loopItemName, loopIndexName, parentLoopVars);
    }
  }

  // 如果当前节点有循环，处理其子节点时需要将当前循环变量添加到父级循环变量列表中
  if (node.loop && node.loopArgs) {
    const currentLoopItemName = node.loopArgs[0] || 'item';
    const currentLoopIndexName = node.loopArgs[1] || 'index';
    const updatedParentLoopVars = [...parentLoopVars, loopItemName, loopIndexName];

    // 递归处理子节点，将当前循环变量作为父级循环变量传递
    if (node.children) {
      if (Array.isArray(node.children)) {
        node.children.forEach((child) =>
          processLoopVariables(
            child,
            currentLoopItemName,
            currentLoopIndexName,
            updatedParentLoopVars,
          ),
        );
      } else {
        processLoopVariables(
          node.children,
          currentLoopItemName,
          currentLoopIndexName,
          updatedParentLoopVars,
        );
      }
    }
  }
}

/**
 * 处理属性值中的循环变量引用
 */
function processPropertyValue(
  value: any,
  loopItemName: string,
  loopIndexName: string,
  setValue: (newValue: any) => void,
  parentLoopVars: string[] = [],
): void {
  // 处理字符串类型的值
  if (typeof value === 'string') {
    let newValue = value;

    // 处理当前循环变量
    if (value.includes(`this.${loopItemName}`)) {
      newValue = newValue.replace(new RegExp(`this\\.${loopItemName}`, 'g'), loopItemName);
    }
    if (value.includes(`this.${loopIndexName}`)) {
      newValue = newValue.replace(new RegExp(`this\\.${loopIndexName}`, 'g'), loopIndexName);
    }

    // 处理父级循环变量
    parentLoopVars.forEach((parentVar) => {
      if (newValue.includes(`this.${parentVar}`)) {
        newValue = newValue.replace(new RegExp(`this\\.${parentVar}`, 'g'), parentVar);
      }
    });

    if (newValue !== value) {
      setValue(newValue);
    }
    return;
  }

  // 处理对象类型的值
  if (value && typeof value === 'object') {
    // 处理JSExpression
    if (value.type === 'JSExpression' && typeof value.value === 'string') {
      let newValue = value.value;

      // 处理当前循环变量
      if (value.value.includes(`this.${loopItemName}`)) {
        newValue = newValue.replace(new RegExp(`this\\.${loopItemName}`, 'g'), loopItemName);
      }
      if (value.value.includes(`this.${loopIndexName}`)) {
        newValue = newValue.replace(new RegExp(`this\\.${loopIndexName}`, 'g'), loopIndexName);
      }

      // 处理父级循环变量
      parentLoopVars.forEach((parentVar) => {
        if (newValue.includes(`this.${parentVar}`)) {
          newValue = newValue.replace(new RegExp(`this\\.${parentVar}`, 'g'), parentVar);
        }
      });

      if (newValue !== value.value) {
        value.value = newValue;
      }
      return;
    }

    // 处理JSFunction
    if (value.type === 'JSFunction' && typeof value.value === 'string') {
      let functionValue = value.value;

      // 处理当前循环变量
      if (functionValue.includes(`this.${loopItemName}`)) {
        functionValue = functionValue.replace(
          new RegExp(`this\\.${loopItemName}`, 'g'),
          loopItemName,
        );
      }
      if (functionValue.includes(`this.${loopIndexName}`)) {
        functionValue = functionValue.replace(
          new RegExp(`this\\.${loopIndexName}`, 'g'),
          loopIndexName,
        );
      }

      // 处理父级循环变量
      parentLoopVars.forEach((parentVar) => {
        if (functionValue.includes(`this.${parentVar}`)) {
          functionValue = functionValue.replace(new RegExp(`this\\.${parentVar}`, 'g'), parentVar);
        }
      });

      if (functionValue !== value.value) {
        value.value = functionValue;
      }
      return;
    }

    // 处理数组
    if (Array.isArray(value)) {
      value.forEach((item, index) => {
        processPropertyValue(
          item,
          loopItemName,
          loopIndexName,
          (newItem) => {
            value[index] = newItem;
          },
          parentLoopVars,
        );
      });
      return;
    }

    // 处理普通对象（递归处理所有属性）
    if (!value.type && typeof value === 'object') {
      Object.keys(value).forEach((key) => {
        processPropertyValue(
          value[key],
          loopItemName,
          loopIndexName,
          (newValue) => {
            value[key] = newValue;
          },
          parentLoopVars,
        );
      });
      return;
    }
  }
}

/**
 * JSX 生成逻辑插件。在 React 代码模式下生成 loop 相关的逻辑代码
 * @type NodePlugin Extended
 *
 * @export
 * @param {IPublicTypeNodeSchema} nodeItem 当前 UI 节点
 * @returns {CodePiece[]} 实现功能的相关代码片段
 */
export function generateReactLoopCtrl(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
  next?: NodePlugin,
): CodePiece[] {
  if (nodeItem.loop) {
    // const tolerateEvalErrors = config?.tolerateEvalErrors ?? true;
    const tolerateEvalErrors = false;

    const loopItemName = nodeItem.loopArgs?.[0] || 'item';
    const loopIndexName = nodeItem.loopArgs?.[1] || 'index';

    // 获取当前作用域中的所有绑定变量（可能是父级循环的变量）
    const parentLoopVars = scope.bindings?.getAllBindings() || [];

    // 递归处理节点中的循环变量引用，包括当前节点的loop属性
    processLoopVariables(nodeItem, loopItemName, loopIndexName, parentLoopVars);

    // 新建作用域，将循环变量添加到作用域中
    const subScope = scope.createSubScope([loopItemName, loopIndexName]);

    const pieces: CodePiece[] = next ? next(nodeItem, subScope, config) : [];

    // 生成循环变量表达式
    const loopDataExpr = pipe(
      nodeItem.loop,
      // 将 JSExpression 转换为 JS 表达式代码:
      (expr) =>
        generateCompositeType(expr, scope, {
          handlers: config?.handlers,
          tolerateEvalErrors: false, // 这个内部不需要包 try catch, 下面会统一加的
          loopItemName, // 传递循环变量名称
          loopIndexName, // 传递循环索引名称
        }),
      // 如果要容忍错误，则包一层 try catch (基于助手函数 __$$evalArray)
      (expr) => (tolerateEvalErrors ? `__$$evalArray(() => (${expr}))` : expr),
    );

    // 使用箭头函数，直接访问循环变量
    pieces.unshift({
      value: `(${loopDataExpr}).map((${loopItemName}, ${loopIndexName}) => (`,
      type: PIECE_TYPE.BEFORE,
    });

    pieces.push({
      value: `))`,
      type: PIECE_TYPE.AFTER,
    });

    if (nodeItem.loop && isJSExpression(nodeItem.condition)) {
      const conditionExpression = pieces[1].value?.slice(0, -1);
      pieces.splice(1, 1);
      pieces.splice(pieces.length - 2, 1);
      pieces[0].value = conditionExpression + pieces[0].value;
    }

    return pieces;
  }

  return next ? next(nodeItem, scope, config) : [];
}

/**
 * JSX 生成逻辑插件。在 React 代码模式下生成 condition 相关的逻辑代码
 * @type NodePlugin
 *
 * @export
 * @param {IPublicTypeNodeSchema} nodeItem 当前 UI 节点
 * @returns {CodePiece[]} 实现功能的相关代码片段
 */
export function generateConditionReactCtrl(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
  next?: NodePlugin,
): CodePiece[] {
  const pieces: CodePiece[] = next ? next(nodeItem, scope, config) : [];

  if (nodeItem.condition != null && nodeItem.condition !== true) {
    // 处理条件表达式中的循环变量引用
    const bindings = scope.bindings?.getAllBindings() || [];
    if (
      bindings.length > 0 &&
      typeof nodeItem.condition === 'object' &&
      'type' in nodeItem.condition &&
      nodeItem.condition.type === 'JSExpression' &&
      'value' in nodeItem.condition
    ) {
      const conditionValue = nodeItem.condition.value as string;
      let newConditionValue = conditionValue;

      bindings.forEach((binding) => {
        const pattern = new RegExp(`\\bthis\\.${binding}\\b`, 'g');
        if (pattern.test(newConditionValue)) {
          newConditionValue = newConditionValue.replace(pattern, binding);
        }
      });

      if (newConditionValue !== conditionValue) {
        nodeItem.condition.value = newConditionValue;
      }
    }

    // 直接使用generateCompositeType，不需要额外的this转换
    const value = generateCompositeType(nodeItem.condition, scope, {
      handlers: config?.handlers,
      isJSSlotParams: true, // 标记为JSSlot参数，确保添加this.前缀
    });

    pieces.unshift({
      value: `${value.startsWith('!') ? '' : '!!'}(${value}) && (`,
      type: PIECE_TYPE.BEFORE,
    });

    pieces.push({
      value: ')',
      type: PIECE_TYPE.AFTER,
    });
  }

  return pieces;
}

/**
 * JSX 生成逻辑插件。在 React 代码模式下，如果 Node 生成结果是一个表达式，则对其进行 { Expression } 包装
 * @type NodePlugin
 *
 * @export
 * @param {IPublicTypeNodeSchema} nodeItem 当前 UI 节点
 * @returns {CodePiece[]} 实现功能的相关代码片段
 */
export function generateReactExprInJS(
  nodeItem: IPublicTypeNodeSchema,
  scope: IScope,
  config?: NodeGeneratorConfig,
  next?: NodePlugin,
): CodePiece[] {
  const pieces: CodePiece[] = next ? next(nodeItem, scope, config) : [];

  if ((nodeItem.condition != null && nodeItem.condition !== true) || nodeItem.loop != null) {
    pieces.unshift({
      value: '{',
      type: PIECE_TYPE.BEFORE,
    });

    pieces.push({
      value: '}',
      type: PIECE_TYPE.AFTER,
    });
  }

  return pieces;
}

const handleChildren = (v: string[]) => v.join('');

export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerator<string> {
  const generateNode = (nodeItem: IPublicTypeNodeDataType, scope: IScope): string => {
    // 添加调试信息
    __log('【generateNode】输入数据类型:', typeof nodeItem);
    __log('【generateNode】输入数据:', nodeItem);

    if (_.isArray(nodeItem)) {
      const resList = nodeItem.map((n) => generateNode(n, scope));
      return handleChildren(resList);
    }

    if (isNodeSchema(nodeItem)) {
      __log('【generateNode】检测到节点结构，生成 JSX');
      return generateNodeSchema(nodeItem, scope, {
        ...cfg,
        self: generateNode,
      });
    }

    __log('【generateNode】不是节点结构，当作复合类型处理');
    const valueStr = generateCompositeType(nodeItem, scope, {
      handlers: cfg.handlers,
      nodeGenerator: generateNode,
    });

    if (isPureString(valueStr)) {
      __log('【generateNode】检测到纯字符串，返回编码后的内容');
      return encodeJsxStringNode(getStaticExprValue<string>(valueStr));
    }

    return `{${valueStr}}`;
  };

  return (nodeItem: IPublicTypeNodeDataType, scope: IScope) =>
    unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
}

// 修改默认配置
const defaultReactGeneratorConfig: NodeGeneratorConfig = {
  nodePlugins: [generateReactExprInJS, generateReactLoopCtrl, generateConditionReactCtrl],
  attrPlugins: [],
};

export function createReactNodeGenerator(cfg?: NodeGeneratorConfig): NodeGenerator<string> {
  const newCfg = mergeNodeGeneratorConfig(defaultReactGeneratorConfig, cfg);
  const baseGenerator = createNodeGenerator(newCfg);

  // 包装函数，处理字符串形式的JSON配置
  return (nodeItem: IPublicTypeNodeDataType, scope: IScope): string => {
    __log('【createReactNodeGenerator】输入数据类型:', typeof nodeItem);

    // 如果是字符串且看起来像JSON配置，先解析
    if (typeof nodeItem === 'string' && nodeItem.trim().startsWith('{')) {
      __log('【createReactNodeGenerator】检测到可能的JSON字符串，尝试解析');
      try {
        // 检查是否包含组件配置特征
        const trimmed = nodeItem.trim();
        if (trimmed.includes('"componentName"') && trimmed.includes('"Page"')) {
          const parsedNodeItem = JSON.parse(nodeItem);
          __log('【createReactNodeGenerator】检测到Page组件JSON，解析成功');
          return baseGenerator(parsedNodeItem, scope);
        }
      } catch (e) {
        __log('【createReactNodeGenerator】JSON解析失败，使用原始数据:', e);
      }
    }

    return baseGenerator(nodeItem, scope);
  };
}
